﻿namespace Sidvall.CodeGenerator
{
	public static class StringExtension
	{
		#region Append

		public static string Append(this string value, string text, string separator)
		{
			if (!string.IsNullOrWhiteSpace(text))
			{
				if (!string.IsNullOrWhiteSpace(value))
				{
					if (separator != null)
						return value + separator + text;
					else
						return value + text;
				}
				else
					return text;
			}
			return value;
		}

		#endregion
		#region Contains

		public static bool Contains(this string value, string text, System.StringComparison comparison)
		{
			int index;

			if (value == null)
				return false;
			if (text == null)
				return false;
			index = value.IndexOf(text, comparison);
			if (index != -1)
				return true;
			return false;
		}

		#endregion
		#region Equals

		public static bool Equals(this string value, string text, bool ignoreWhiteSpace, System.StringComparison comparison)
		{
			if (ignoreWhiteSpace)
			{
				if (string.IsNullOrWhiteSpace(value))
				{
					if (string.IsNullOrWhiteSpace(text))
						return true;
					else
						return false;
				}
				if (string.IsNullOrWhiteSpace(text))
					return false;
				return value.Equals(text, comparison);
			}
			else
			{
				if (value == null)
				{
					if (text == null)
						return true;
					else
						return false;
				}
				if (text == null)
					return false;
				return value.Equals(text, comparison);
			}
		}

		#endregion
		#region Replace

		public static string Replace(this string value, string oldValue, string newValue, System.StringComparison comparison)
		{
			System.Text.StringBuilder sb;
			int index, previousIndex;

			if (value == null)
				return value;
			if (oldValue == null)
				return value;
			sb = new System.Text.StringBuilder();
			previousIndex = 0;
			index = value.IndexOf(oldValue, comparison);
			while (index != -1)
			{
				sb.Append(value.Substring(previousIndex, index - previousIndex));
				sb.Append(newValue);
				index += oldValue.Length;

				previousIndex = index;
				index = value.IndexOf(oldValue, index, comparison);
			}
			sb.Append(value.Substring(previousIndex));

			return sb.ToString();
		}

		#endregion
		#region Split

		public static string[] Split(this string value, string separator)
		{
			return Split(value, separator, System.StringSplitOptions.None);
		}
		public static string[] Split(this string value, string separator, System.StringSplitOptions options)
		{
			if (string.IsNullOrWhiteSpace(value))
				return null;
			return value.Split(new string[] { separator }, options);
		}

		#endregion

		#region ToEnum

		public static T ToEnum<T>(this string value, T defaultValue) where T : struct
		{
			T? result;

			result = value.ToNullableEnum<T>();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToBoolean

		public static bool ToBoolean(this string value, bool defaultValue)
		{
			bool? result;

			result = value.ToNullableBoolean();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToChar

		public static char ToChar(this string value, char defaultValue)
		{
			char? result;

			result = value.ToNullableChar();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToDateTime

		public static System.DateTime ToDateTime(this string value, System.DateTime defaultValue)
		{
			System.DateTime? result;

			result = value.ToNullableDateTime();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToDateTimeOffset

		public static System.DateTimeOffset ToDateTimeOffset(this string value, System.DateTimeOffset defaultValue)
		{
			System.DateTimeOffset? result;

			result = value.ToNullableDateTimeOffset();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToDecimal

		public static decimal ToDecimal(this string value, decimal defaultValue)
		{
			decimal? result;

			result = value.ToNullableDecimal();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToDouble

		public static double ToDouble(this string value, double defaultValue)
		{
			double? result;

			result = value.ToNullableDouble();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToByte

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "int8")]
		public static byte ToByte(this string value, byte defaultValue)
		{
			byte? result;

			result = value.ToNullableByte();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToInt16

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "int16")]
		public static short ToInt16(this string value, short defaultValue)
		{
			short? result;

			result = value.ToNullableInt16();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToInt32

		public static int ToInt32(this string value, int defaultValue)
		{
			int? result;

			result = value.ToNullableInt32();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToInt64

		public static long ToInt64(this string value, long defaultValue)
		{
			long? result;

			result = value.ToNullableInt64();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToSingle

		public static float ToSingle(this string value, float defaultValue)
		{
			float? result;

			result = value.ToNullableSingle();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToTimeSpan

		public static System.TimeSpan ToTimeSpan(this string value, System.TimeSpan defaultValue)
		{
			System.TimeSpan? result;

			result = value.ToNullableTimeSpan();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion
		#region ToGuid

		public static System.Guid ToGuid(this string value, System.Guid defaultValue)
		{
			System.Guid? result;

			result = value.ToNullableGuid();
			if (result == null)
				return defaultValue;

			return result.Value;
		}

		#endregion

		#region ToNullableEnum

		public static T? ToNullableEnum<T>(this string value) where T : struct
		{
			T result;

			if (string.IsNullOrWhiteSpace(value))
				return null;
			if (System.Enum.TryParse<T>(value, true, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableBoolean

		public static bool? ToNullableBoolean(this string value)
		{
			bool result;

			if (string.IsNullOrWhiteSpace(value))
				return null;
			if (bool.TryParse(value, out result))
				return result;
			if ((value == "0") ||
				(value.Equals("false", System.StringComparison.OrdinalIgnoreCase)) ||
				(value.Equals("n", System.StringComparison.OrdinalIgnoreCase)) ||
				(value.Equals("no", System.StringComparison.OrdinalIgnoreCase)))
			{
				return false;
			}
			else if ((value == "1") ||
				(value.Equals("true", System.StringComparison.OrdinalIgnoreCase)) ||
				(value.Equals("y", System.StringComparison.OrdinalIgnoreCase)) ||
				(value.Equals("yes", System.StringComparison.OrdinalIgnoreCase)))
			{
				return true;
			}

			return null;
		}

		#endregion
		#region ToNullableChar

		public static char? ToNullableChar(this string value)
		{
			char result;

			if (string.IsNullOrWhiteSpace(value))
				return null;
			if (char.TryParse(value, out result))
				return result;

			return null;
		}

		#endregion
		#region ToNullableDateTime

		public static System.DateTime? ToNullableDateTime(this string value)
		{
			System.DateTime result;

			if (System.DateTime.TryParse(value, out result))
				return result;
			if (System.DateTime.TryParse(value, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableDateTimeOffset

		public static System.DateTimeOffset? ToNullableDateTimeOffset(this string value)
		{
			System.DateTimeOffset result;

			if (System.DateTimeOffset.TryParse(value, out result))
				return result;
			if (System.DateTimeOffset.TryParse(value, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableDecimal

		public static decimal? ToNullableDecimal(this string value)
		{
			decimal result;

			if (decimal.TryParse(value, out result))
				return result;
			if (decimal.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableDouble

		public static double? ToNullableDouble(this string value)
		{
			double result;

			if (double.TryParse(value, out result))
				return result;
			if (double.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableByte

		public static byte? ToNullableByte(this string value)
		{
			byte result;
			if (byte.TryParse(value, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableInt16

		public static short? ToNullableInt16(this string value)
		{
			short result;
			if (short.TryParse(value, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableInt32

		public static int? ToNullableInt32(this string value)
		{
			int result;
			if (int.TryParse(value, out result))
				return result;
			if (int.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableInt64

		public static long? ToNullableInt64(this string value)
		{
			long result;
			if (long.TryParse(value, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableSingle

		public static float? ToNullableSingle(this string value)
		{
			float result;

			if (float.TryParse(value, out result))
				return result;
			if (float.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableTimeSpan

		public static System.TimeSpan? ToNullableTimeSpan(this string value)
		{
			System.TimeSpan result;

			if (System.TimeSpan.TryParse(value, out result))
				return result;
			if (System.TimeSpan.TryParse(value, System.Globalization.CultureInfo.InvariantCulture, out result))
				return result;
			return null;
		}

		#endregion
		#region ToNullableGuid

		public static System.Guid? ToNullableGuid(this string value)
		{
			System.Guid result;

			if (System.Guid.TryParse(value, out result))
				return result;
			return null;
		}

		#endregion
	}
}
